﻿<!doctype html>
<html>
<head>
    <title>SpreadJS - Custom Item Serialize</title>
    <meta charset="utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>

    <link href="../../../external/spreadjs/css/gcspread.sheets.excel2013white.9.40.20161.0.css" rel="stylesheet" type="text/css" />

    <script src="../../../external/external/jquery-1.8.2.min.js" type="text/javascript"></script>

    <script type="text/javascript" src="../../../external/spreadjs/gcspread.sheets.all.9.40.20161.0.min.js"></script>

    <script id="scriptInit" type="text/javascript">
        /*code_begin*/
        var spreadNS = GcSpread.Sheets;

        // Define custom cellType
        function MyCellType(color) {
            spreadNS.CustomCellType.apply(this, arguments);
            this.color = color || "orange";
            this.typeName = "MyCellType";
        }
        MyCellType.prototype = new spreadNS.CustomCellType();
        MyCellType.prototype.paint = function (ctx, value, x, y, width, height, style, context) {
            var MARGIN = 5,
                plotLeft = x + MARGIN,
                plotWidth = width - 2 * MARGIN,
                plotTop = y + MARGIN,
                plotHeight = height - 2 * MARGIN,
                halfHeight = plotHeight / 2,
                halfWidth = plotWidth / 2;

            ctx.beginPath();
            ctx.moveTo(plotLeft, plotTop + halfHeight);
            ctx.lineTo(plotLeft + halfWidth, plotTop);
            ctx.lineTo(plotLeft + plotWidth, plotTop + halfHeight);
            ctx.lineTo(plotLeft + halfWidth, plotTop + plotHeight);
            ctx.lineTo(plotLeft, plotTop + halfHeight);
            ctx.strokeStyle = this.color;
            ctx.stroke();
        };

        // Define custom tag
        function MyTag(name, age) {
            this.name = name;
            this.age = age;
            this.typeName = "MyTag";
        }
        MyTag.prototype.toJSON = function () {
            return {
                typeName: this.typeName,//necessary
                name: this.name,
                age: this.age
            };
        };
        MyTag.prototype.fromJSON = function (settings) {
            if (settings.name !== undefined) {
                this.name = settings.name;
            }
            if (settings.age !== undefined) {
                this.age = settings.age;
            }
        };

        var mynamespace = {};
        (function () {
            // Define custom function (with namespace)
            function MyFunction() {
                spreadNS.Calc.Functions.Function.apply(this, ["MyFunction", 0, 0]);
                this.typeName = "mynamespace.MyFunction";
            }
            MyFunction.prototype = new spreadNS.Calc.Functions.Function();
            MyFunction.prototype.evaluate = function (args) {
                var now = new Date();
                return now.getFullYear() + "/" + (now.getMonth() + 1) + "/" + now.getDate();
            };
            mynamespace.MyFunction = MyFunction;

            // Define custom sparklineEx (with namespace)
            function MySparklineEx() {
                spreadNS.SparklineEx.apply(this, arguments);
                this.typeName = "mynamespace.MySparklineEx";
            }
            MySparklineEx.prototype = new spreadNS.SparklineEx();
            MySparklineEx.prototype.createFunction = function () {
                var func = new spreadNS.Calc.Functions.Function("CIRCLE", 0, 0);
                func.evaluate = function (args) {
                    return {};
                };
                return func;
            };
            MySparklineEx.prototype.paint = function (context, value, x, y, width, height) {
                context.beginPath();
                context.arc(x + width / 2, y + height / 2, (Math.min(width, height) - 6) / 2, 0, Math.PI * 2);
                context.strokeStyle = "orange";
                context.stroke();
            };
            mynamespace.MySparklineEx = MySparklineEx;
        })();

        $(document).ready(function () {
            var spread = new GcSpread.Sheets.Spread(document.getElementById("ss"), { sheetCount: 6 });
            var spread2 = new GcSpread.Sheets.Spread(document.getElementById("ss1"), { sheetCount: 1 });
            initSpread(spread);
        });

        function initSpread(spread) {
            var   tagSheetIndex, rowFilterSheetIndex;

            var digitMap = [
                { label: "Zero", value: 0 },
                { label: "One", value: 1 },
                { label: "Two", value: 2 },
                { label: "Three", value: 3 },
                { label: "Four", value: 4 },
                { label: "Five", value: 5 },
                { label: "Six", value: 6 },
                { label: "Seven", value: 7 },
                { label: "Eight", value: 8 },
                { label: "Nine", value: 9 },
                { label: "Ten", value: 10 }
            ];

            // Define custom formatter (private in function)
            function MyFormatter(format, cultureName) {
                spreadNS.CustomFormatterBase.apply(this, arguments);
                this.typeName = "MyFormatter";
            }
            MyFormatter.prototype = new spreadNS.CustomFormatterBase();
            MyFormatter.prototype.Parse = function (str) {
                var labels = digitMap.map(function (item) { return item.label; }),
                    index = labels.indexOf(str);

                if (index === -1) {
                    index = parseInt(str);
                }

                return (index < 0 || index > 10) ? NaN : index;
            };
            MyFormatter.prototype.Format = function (obj, conditionalForeColor) {
                var numbers = digitMap.map(function (item) { return item.value }),
                    index = numbers.indexOf(obj);

                return index === -1 ? "NaN" : digitMap[index].label;
            };

            // Define custom row filter (private in function)
            function MyRowFilter(range) {
                spreadNS.RowFilterBase.apply(this, arguments);
                this.typeName = "MyRowFilter";
            }
            MyRowFilter.prototype = new spreadNS.RowFilterBase();
            MyRowFilter.prototype.onFilter = function (args) {
                if (args.action === spreadNS.FilterActionType.Filter) {
                    var sheet = args.sheet,
                        range = args.range,
                        filterdRows = args.filteredRows,
                        filteredOutRows = args.filteredOutRows;
                    if (range.row < 0) {
                        range.row = 0;
                        range.rowCount = sheet.getRowCount();
                    }
                    if (range.col < 0) {
                        range.col = 0;
                        range.colCount = sheet.getColumnCount();
                    }
                    for (var i = 0, filterdRowCount = filterdRows.length; i < filterdRowCount; i++) {
                        var rowIndex = filterdRows[i];
                        sheet.getCells(rowIndex, range.col, rowIndex, range.col + range.colCount - 1).backColor("red");
                    }
                }
            };

            var oldFun = spreadNS.getTypeFromString;
            // Private types can not be accessed from window, so override getTypeFromString method.
            spreadNS.getTypeFromString = function (typeString) {
                switch(typeString) {
                    case "MyFormatter":
                        return MyFormatter;
                    case "MyRowFilter":
                        return MyRowFilter;
                    default:
                        return oldFun.apply(this, arguments);
                }
            };
            
            spread.isPaintSuspended(true);
            spread.allowSheetReorder(false);
            spread.setTabStripRatio(0.9);

            var sheet = spread.getSheet(0);
            sheet.setName("Cell type");
            sheet.setCellType(0, 0, new MyCellType("green"));
            sheet.setRowHeight(0, 60);

            sheet = spread.getSheet(1);
            sheet.setName("Function");
            sheet.addCustomFunction(new mynamespace.MyFunction());
            sheet.setFormula(0, 0, "MyFunction()");
            sheet.setColumnWidth(0, 150);

            sheet = spread.getSheet(2);
            sheet.setName("Formatter");
            sheet.setValue(0, 0, 1);
            sheet.setFormatter(0, 0, new MyFormatter());
            sheet.setFormula(0, 1, "A1");

            sheet = spread.getSheet(3);
            sheet.setName("SparklineEx");
            spread.addSparklineEx(new mynamespace.MySparklineEx());
            sheet.setFormula(0, 0, "CIRCLE()");
            sheet.setRowHeight(0, 60);

            tagSheetIndex = 4;
            sheet = spread.getSheet(tagSheetIndex);
            sheet.setName("Tag");
            sheet.tag(new MyTag("Ivy", 24));
            sheet.setTag(0, 0, new MyTag("Yang", 25));
            sheet.allowCellOverflow(true);
            sheet.setValue(0, 0, "Please check tag serialization result in console");

            rowFilterSheetIndex = 5;
            sheet = spread.getSheet(rowFilterSheetIndex);
            sheet.setName("Row Filter");
            for (var r = 0; r < 3; r++) {
                for (var c = 0; c < 3; c++) {
                    sheet.setValue(r, c, r + c);
                }
            }
            sheet.rowFilter(new MyRowFilter(new spreadNS.Range(0, 0, 3, 3)));
            sheet.rowFilter().addNumberFilter(0, spreadNS.GeneralCompareType.GreaterThan, 1);

            spread.isPaintSuspended(false);

            $("#fromtoJsonBtn").click(function () {
                // ToJson
                var spread1 = $("#ss").data("spread");
                var jsonStr = JSON.stringify(spread1.toJSON());

                // FromJson
                var spread2 = $("#ss1").data("spread");
                spread2.fromJSON(JSON.parse(jsonStr));

                // Tag verify
                var sheet = spread1.getSheet(tagSheetIndex);
                console.log("Source spread:");
                console.log("Sheet tag: ", sheet.tag());
                console.log("Cell Tag: ", sheet.getTag(0, 0));

                var sheet2 = spread2.getSheet(tagSheetIndex);
                console.log("Target spread:");
                console.log("Sheet tag: ", sheet2.tag());
                console.log("Cell Tag: ", sheet2.getTag(0, 0));
            });

            $("#filter").click(function () {
                var spread1 = $("#ss").data("spread");
                spread1.getSheet(rowFilterSheetIndex).rowFilter().filter();

                var spread2 = $("#ss1").data("spread");
                spread2.getSheet(rowFilterSheetIndex).rowFilter().filter();
            });
        }
        /*code_end*/
    </script>

</head>
<body class="demo-single">
    <div class="sample-turtorial">
        <label>Source:</label>
        <div id="ss" style="width:100%;height:265px;border: 1px solid gray; margin-bottom: 5px;margin-right:10px;"></div>
        <br/>
        <label style="font:bold 10pt arial">Target:</label>
        <div id="ss1" style="width:100%;height:265px;border: 1px solid gray; margin-bottom: 5px;" ></div>
        <div class="demo-options">
            <div class="option-row">
                <input type="button" id="fromtoJsonBtn" value="Json Serialize" title="Serialize source spread to JSON and restore from JSON to target spread."/>
                <input type="button" id="filter" value="Filter" title="Apply custom filter" />
            </div>
        </div>
    </div>
</body>
</html>
